﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using MR_HKSFilereader;

namespace MR_HKSCalc
{
    class HKSCalculator
    {
        static void Main(string[] args)
        {
            string[] fileEntries = Directory.GetFiles(args[0]);
            List<String> filenames = new List<String>();
            int fileCount = 0;
            foreach (string fileName in fileEntries)
            {
                if (fileName.EndsWith(".vect"))
                {
                    filenames.Add(Path.GetFileNameWithoutExtension(fileName));
                    fileCount++;
                    CalculateHKT(fileName, fileName.Replace(".vect", ".eval"));
                }
            }

            Storage s = new Storage();
            double[,] distances = new double[fileCount,fileCount];
            for (int i = 0; i < fileCount; i++)
                for (int j = 0; j < fileCount; j++)
                {
                    double[] firstHKS, secondHKS;
                    firstHKS = s.getHKSValues(filenames[i]);
                    secondHKS = s.getHKSValues(filenames[j]);

                    distances[i, j] = euclidianDistance(firstHKS, secondHKS);
                }
            Console.ReadLine();
        }

        public static void CalculateHKT(String file1, String file2)
        {
            List<List<double>> eigenvectors = new List<List<double>>();
            List<double> eigenvalues = new List<double>();

            TextReader reader = new StreamReader(file1);

            string line = reader.ReadLine();
            double value;
            for(int i = 0; line != null; i++)
            {
                string[] split = line.Split(",".ToCharArray());
                if (eigenvectors.Count == 0)
                    for (int j = 0 ; j < split.Length; j++)
                        eigenvectors.Add(new List<double>());
                for(int j = 0; j < split.Length; j++)
                {
                    value = Double.Parse(split[j].Replace(".", ","), System.Globalization.NumberStyles.Float);
                    eigenvectors[j].Add(value);
                }
                line = reader.ReadLine();
            }

            reader.Close();

            reader = new StreamReader(file2);

            line = reader.ReadLine();
            for (int i = 0; line != null; i++)
            {
                string[] split = line.Split(",".ToCharArray());
                value = Double.Parse(split[i].Replace(".", ","), System.Globalization.NumberStyles.Float);
                eigenvalues.Add(value);
                line = reader.ReadLine();
            }

            reader.Close();

            double[,] eigenvectormatrix = new double[eigenvectors.Count, eigenvectors[0].Count];
            for (int i = 0; i < eigenvectormatrix.GetLength(0); i++)
                for (int j = 0; j < eigenvectormatrix.GetLength(1); j++)
                    eigenvectormatrix[i, j] = eigenvectors[i][j];
            //Calculate values for t
            double tmin, tmax, stepsize;
            tmin = 4 * Math.Log(10) / eigenvalues[1];
            tmax = 4 * Math.Log(10) / eigenvalues[eigenvalues.Count - 1];
            stepsize = (Math.Log(tmax) - Math.Log(tmin)) / 100;
            double[] hksvals = new double[eigenvalues.Count];
            for (int x = 0; x < eigenvectormatrix.GetLength(0); x++)
            {
                double hks = 0;
                for (int i = 0; i < 100; i++)
                {
                    double todiv = 0;
                    for (int j = 0; j < eigenvalues.Count; j++)
                        todiv += Math.Exp(-(Math.Log(tmin) + i* stepsize) * eigenvalues[j]);
                    hks += HKT(x, Math.Log(tmin) + i * stepsize, eigenvectormatrix, eigenvalues) / todiv;
                }
                hksvals[x] = hks;
            }
            Storage s = new Storage();
            s.saveHKSValues(Path.GetFileNameWithoutExtension(file1), hksvals);
            double[] res = s.getHKSValues(Path.GetFileNameWithoutExtension(file1));
            
        }

        private static double HKT(int x, double t, double[,] eigenvectors, List<double> eigenvalues)
        {
            double result = 0;
            for (int i = 0; i < eigenvectors.GetLength(0); i++)
            {
                result += (Math.Exp(-eigenvalues[i] * t) * eigenvectors[i,x] * eigenvectors[i,x]);
            }
            return result;
        }
        private static double euclidianDistance(double[] vector1, double[] vector2)
        {
            double distance = 0;
            for (int i = 0; i < vector1.GetLength(0); i++)
            {
                distance += Math.Pow(vector1[i] - vector2[i], 2);
            }
            return Math.Sqrt(distance);
        }



    }
}
